成品連結:Flex Panel Gallery,HTML & CSS 程式碼
今天的作品其實寫的 JS code 並不多,與前面有許多重複的地方,反而較著重於 CSS Flex 的操作部分。
一開始的畫面長這樣,但我們想要五個區塊可以垂直並排,而不是水平並排。
首先在 CSS .panels
寫入 display: flex
,可以看到五個區塊的排序方式改變了,但卻縮成一團在畫面左側,那是因為我們並沒有給予 class panel
寬度,所以各個 panel
只會依照其中的元素寬來制定寬度。因此我們要在 .panel
的 CSS 寫入:
.panel {
flex: 1;
}
意思是當父容器還有空間時自動延縮大小,每個 panel 都各佔一等份。
接著要設定 .panel
中 p 的樣式,由於我想使用 flex 的 justify-content 以及 align-items 功能,所以首先在 .panel
寫入 display: flex
,也就是說 .panel
本身是 flex-item 同時也是 flex-container,接著設定一下格式
.panel {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
}
現在雛形出來了,接著要把原本在上下方的 p
隱藏,並在之後透過監聽事件再出現;因此我們使用 transform
的 translateY
屬性來垂直移動
.panel > *:first-clild {
transform: translateY(-400%);
}
.panel > *:last-child {
transform: translateY(400%);
}
最後希望在點擊後該 panel
會變大、並出現隱藏的上、下文字。預期的效果是當點擊時區塊變大,而當變大效果結束後出現上下文字
.panel.open {
font-size: 40px;
flex: 5;
}
.panel.open-active > *:first-child, .panel.open-active > *:last-child {
transform: translateY(0);
}
到這裡 CSS 的部分完成了!剩下的只有設定監聽事件了
先選取每個 panel
const panels = document.querySelectorAll('.panel');
接著在每個 panel
分別設定點擊監聽事件,使在點擊後 .panel
會切換 open
這個 class,使區塊能呈現伸縮動畫
panels.forEach(cur => cur.addEventListener('click', toggleOpen));
function toggleOpen() {
// this 代表被點擊的 panel
this.classList.toggle('open');
}
最後的最後,當 click 事件動畫結束後,使 panel
中隱藏的 p
段落出現,所以我們需要再設定新的監聽事件,使用的事件類別是第一天用過的 transitionend
// 當 open 動畫結束後加上 open-active
panels.forEach(cur => cur.addEventListener('transitionend', toggleActive));
function toggleActive(e) {
// e.property 會同時有 font-size 以及 flex-grow 兩項,但我們只希望有一項
if(e.propertyName !== 'flex-grow') return;
e.target.classList.toggle('open-active');
}
然後就完成了!漂亮!